<?php

namespace App\Http\Controllers;

use App\Models\BlogBook;
use App\Models\BlogProfile;
use App\Models\BlogRole;
use App\Models\BlogUser;
use App\Models\CheckUser;
use Barryvdh\Debugbar\Facades\Debugbar;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use function Symfony\Component\Mime\Header\get;

class DataController extends Controller
{
    public function index(){

        //Debugbar调试器
//        Debugbar::enable();
//        Debugbar::info('信息');
//        $users = BlogUser::all();
//        foreach ($users as $user){
////            Debugbar::info($user->username);
//            Debugbar::info($user->toJson());
//        }
//        return view('data');

        /*
        //原生SQL
        $user = \DB::select('select * from blog_users');
        //return $user;

        //查询构造器
        $user = \DB::table('blog_users')->find(4);
        //return response()->json($user);
        //return $user;

        //模型
        $user = BlogUser::all();
        //return $user;

        //获取表的所有数据  get()
        $users = \DB::table('blog_users')->get();

        //获取指定表第一条数据 first()
        $users = \DB::table('blog_users')->first();

        //获取指定表第一条数据的某个字段的值 value('字段名')
        $users = \DB::table('blog_users')->value('username');

        //获取指定id的一条数据 find('id值')
        $users = \DB::table('blog_users')->find(4);

        //获取表中指定字段所有值 pluck('字段名')
        $users = \DB::table('blog_users')->pluck('username');
        $users = \DB::table('blog_users')->pluck('username','id');

        //数据过多防止出错，分块处理 chunk('数量',函数)
        /*DB::table('blog_users')->orderBy('id')->chunk(3,function ($users){
            foreach ($users as $user){
                echo $user->username;
            }
            echo '-----<br>----';
        });*/

        //return response()->json($users);

        //返回数据条数 count()
        //return DB::table('blog_users') -> count();

        //返回列的平均数 avg('列名')
        //返回列的最大值 max('列名')
        //返回列的最小值 min('列名')
        //返回列的总和   sum('列名')
        //return DB::table('blog_users') -> avg('username');

        //判断数据是否存在 exists() / doesntExist():不存在为true
        //return [DB::table('blog_users')->where('id',5)->doesntExist()];
/*
        //查询需要的列，能设置别名
        $users = \DB::table('blog_users')->select('username as name','id')->get();

        //给已经构建好的查询添加更多字段
        $data = \DB::table('blog_users')->select('username as 用户名');
        $users = $data->addSelect('password as 密码')->get();
        //return $users;

        //1.结合原生SQL实现复杂查询：根据性别分组
        $users = \DB::table('blog_users')
            ->select(\DB::raw('count(*) as count,sex'))
            ->groupBy('sex')
            ->get();
        //2.也可直接使用selectRaw()方法实现内部原生
        $users = \DB::table('blog_users')
            ->selectRaw('count(*) as count,sex')
            ->groupBy('sex')
            ->get();
        //3.还可以通过havingRaw()方法实现更精准的分组筛选
        $users = \DB::table('blog_users')
            ->selectRaw('count(*) as count,sex')
            ->groupBy('sex')
            ->havingRaw('count<3')
            ->get();

        //where条件默认为:=
        $users = \DB::table('blog_users')->where('id',5)->get();
        $users = \DB::table('blog_users')->where('id','>=',3)->get();
        $users = \DB::table('blog_users')->where('username','like','%小%')->get();
        //条件多时可用数组添加
        $users = \DB::table('blog_users')->where([
            ['id' ,'>=','2'],
            ['sex','女']
        ])->get();

        // 实现两个以上条件查询 orWhere()
        $users = \DB::table('blog_users')->where('id','<','3')
            ->orWhere('sex','女')
            ->get();

        // 通过闭包，构建更加复杂的orWhere查询
        $users = \DB::table('blog_users')->where('id','<','3')
            ->orWhere(function ($query){
                $query->where('sex','女')->where('username','like','%红%');
            })
            ->get();

        //区间查询  whereBetween()  PS：  whereNotBetween/orWhereBetween/orWhereNotBetween
        $users = \DB::table('blog_users')->whereNotBetween('id',[2,4])->get();

        //查询数组里匹配的数据  whereIn('字段名',[数组])  PS： whereNotIn/orWhereIn/orWhereNotIn
        $users = \DB::table('blog_users')->whereIn('id',[2,4,6])->get();

        //查询字段为Null的记录  whereNull('字段名')  PS： whereNotNull/orWhereNull/orWhereNotNull
        $users = \DB::table('blog_users')->whereNull('sex')->get();

        //查询指定日期的记录  whereDate('字段名','日期')
        $users = \DB::table('blog_users')->whereDate('created_at','>','2022-09-20')->get();
        $users = \DB::table('blog_users')->whereYear('created_at','2022')->get();
        $users = \DB::table('blog_users')->whereMonth('created_at','09')->get();
        $users = \DB::table('blog_users')->whereDay('created_at','20')->get();
        $users = \DB::table('blog_users')->whereTime('created_at','>=','14:57:35')->get();

        //查询两个相等的字段 whereColumn()
        $users = \DB::table('blog_users')->whereColumn('created_at','updated_at')->get();

        //按照日期倒序排序  latest()  默认字段为created_at
        $users = \DB::table('blog_users')->latest()->get();

        //随机排序  inRandomOrder()
        $users = \DB::table('blog_users')->inRandomOrder()->get();

        //使用 skip() 和 take() 限制结果集，或使用 offset() 和 limit()
        //从第3条开始，显示3条
        $users = \DB::table('blog_users')->skip(2)->take(3)->get();
        $users = \DB::table('blog_users')->offset(2)->limit(3)->get();

        //使用 when() 方法可以设置条件选择，执行相应的SQL语句
        $users = \DB::table('blog_users')->when(true,function ($query){
            $query->where('id',1);
        },function ($query){
            $query->where('sex','女');
        })->get();


        /*
         * 子查询
         * */
        /*
        //1.使用whereExists()方法实现一个子查询结果，返回相应的主查询
        // 通过books表数据，查询到users表关联的所有用户
        $users = \DB::table('blog_users')->whereExists(function ($query){
            //$query->from('blog_books')->whereRaw('blog_books.uid=blog_users.id');
            $query->from('blog_books')->whereColumn('blog_books.uid','blog_users.id');
        })->get();

        //2.也可以使用where(字段，function())闭包，来实现一个子查询
        // id = 子查询返回的 uid
        $users = \DB::table('blog_users')->where('id',function ($query){
            $query->select('uid')
                ->from('blog_books')
                ->whereColumn('blog_books.uid','blog_users.id');
        })->toSql();

        /*
         * 多表查询
         * */
        //连接查询
        /*
        $users = \DB::table('blog_users')
                ->join('blog_books','blog_books.uid','=','blog_users.id')
                ->join('blog_profiles','blog_profiles.uid','=','blog_users.id')
                ->get();

        //笛卡尔积
        $users = \DB::table('blog_users')
            ->crossJoin('blog_profiles')
            ->select('username','status')
            ->distinct()
            ->get();

        //多表闭包查询,和where类似，只不过要用on和orOn方法
        $users = \DB::table('blog_users')->join('blog_books',function ($join){
            $join->on('blog_books.uid','=','blog_users.id')->where('blog_users.id',5);
        })->get();

        //使用 union() 或 unionAll() 方法实现两个查询的合并操作  表结构必须相同
        //union取消重复，unionAll不取消重复
        $query = \DB::table('blog_users');
        $users = \DB::table('blog_users')
                ->unionAll($query)
                ->get();

        */

        //插入数据 insert()
//        $query = DB::table('blog_users')->insert([
//           'username' => '杜甫',
//            'password' => '123456',
//            'sex' => '男'
//        ]);


        //删除数据 delete() 默认值为id  一般要加上where条件，否则清空
//        DB::table('blog_users')->where('id',9)->delete();
//        DB::table('blog_users')->delete(9);

//        return [$users];

//        $users = BlogUser::get();
//
//        return [$users];

        //模型-新增数据
//        $users = new BlogUser();
//        $users->username = '李白';
//        $users->password = md5('123456789');
//        $users->sex = '男';
//        $users->save();
        //新增数据  create()
//        BlogUser::create([
//            'username' => '测试',
//            'password' => md5('147258'),
//            'sex'      => '男'
//        ]);

        //模型-更新数据  一条数据
//        $users = BlogUser::find(6);
//        $users->sex = '女';
//        $users->save();
        //批量更新数据  update()
//        BlogUser::where('id','>','6')
//            ->update([
//               'password' => '123'
//            ]);

        //模型-删除数据
        //通过查找id进行删除
//        $users = BlogUser::find(24);
//        $users->delete();
        //通过查询其他字段进行删除
//        $users = BlogUser::where('username','测试');
//        $users->delete();
        //不需要查询，直接通过主键删除
//        BlogUser::destroy(21);
//        BlogUser::destroy([1,2,3]);  //批量删除

        //模型作用域
//        $users = BlogUser::sex('女')
//            ->where('id','<','10')
//            ->get();

        //添加测试数据
//        BlogUser::create([
//           'username' => '222222',
//           'password' => '123',
//           'sex' => '男'
//        ]);

        //全局作用域下查询所有数据
//        $users = BlogUser::get();
//
//        return $users;

        //模型关联调用时，调用属性格式
        //模型正向一对一关联，主表调用附表
//        $blogprofiles = BlogUser::find(1)->profile;
//        return $blogprofiles;

        //模型反向一对一关联，附表调用主表
//        $users = BlogProfile::find(1)->user;
//        return $users;

        //模型正向一对多关联
//        $books = BlogUser::find(1)->book;
//        return $books;
        //一对多关联之后再进行筛选       属性需加上()
//        $books = BlogUser::find(1)->book()->where('id','1')->get();
//        return $books;

        //模型一对多反向关联
//        $users = BlogBook::find(1)->user;
//        return $users->username;

        //模型多对多正向关联
//        $roles = BlogUser::find(1)->role;
//        return $roles;


        //模型多对多反向关联
//        $users = BlogRole::find(4)->user;
//        return $users;

        //使用 has() 方法，可以查询某些条件下的关联查询数据
        //获取存在关联书籍的用户列表（言下之意：至少一本书）
//        $books = BlogUser::has('book')->get();
//        return $books;
        //获取存在关联书籍（并超过3条）的用户列表
//        $books = BlogUser::has('book','>=',3)->get();
//        return $books;

        //获取没有关联书籍的用户列表
//        $books = BlogUser::doesntHave('book')->get();
//        return $books;

        //使用whereHas()方法，创建闭包查询
//        $users = BlogUser::whereHas('book',function ($query){
//           $query->where('id',3);
//        })->get();
//        return $users;

        //使用withCount()方法，可以进行关联统计
        //自动添加一个book_acount字段
        //统计每个用户有多少本书
//        $users = BlogUser::withCount('book')->get();
//        return $users;

        //使用Debugbar调试器
//        $books = BlogBook::all();
////        $books = BlogBook::with('user')->get();
//        foreach ($books as $book){
////            Debugbar::info($book->toJson());
//            Debugbar::info($book->toArray());
//        }
//        return view('data');

//        $books = BlogBook::all();
//        foreach ($books as $book){
//            Debugbar::info($book->user->username);
//        }

        //模型的预加载  with()
//        $books = BlogBook::with('user')->get();
//        foreach ($books as $book){
//            Debugbar::info($book->user->username);
//        }

        //模型的关联写入
//        $user = BlogUser::find(1);
////        $user->book()->save(new BlogBook(['book_name' => '哈利波特']));
//        //批量写入
//        $user->book()->saveMany([
//            new BlogBook(['book_name' => '侏罗纪世界']),
//            new BlogBook(['book_name' => '霍比特人'])
//        ]);
//
//        // create 和 createMany 只需插入数组即可完成关联新增
//        $user->book()->create([   //批量：createMany([ [],[] ])
//           'book_name' => ''
//        ]);
//        return view('data');

        //一、多对多关联写入
        //1.多对多的新增  attach()
//        $user = BlogUser::find(3);   //得到要添加权限的用户
//        $roleId = 2;   //得到权限的id，比如超级管理员 2
//        $user->role()->attach($roleId);   //把id为3的用户 小明 设置成权限id为2的权限 超级管理员

        //2.给中间表附加detail字段的数据，可以使用第二参数
//        $user = BlogUser::find(3);   //得到要添加权限的用户
//        $roleId = 2;   //得到权限的id，比如超级管理员 2
//        $user->role()->attach($roleId,['detail' => '拥有至高权限']); //附加detail字段的数据

        //3.删除某个用户的权限，使用 detach()
//        $user = BlogUser::find(3);   //得到要添加权限的用户
//        $roleId = 2;   //得到权限的id，比如超级管理员 2
//        $user->role()->detach($roleId);  //不指定id，则删除这个用户的所有权限

        //4.批量处理，直接用数组传递参数即可
//        $user = BlogUser::find(3);   //得到要添加权限的用户
////        $user->role()->attach([1,2,3]);  //添加多个权限，数组里传递的是权限id
//        $user->role()->attach([
//            1 => ['detail' => '普通权限'],
//            2 => ['detail' => '超级管理员权限'],
//            3 => ['detail' => 'VIP特权'],
//        ]);  //添加多个权限，并分别附加detail字段的数据
//        $user->role()->detach([1,2,3]);  //批量删除多个权限

        //5.新增权限，会判断已存在不再新增  sync()
//        $user = BlogUser::find(3);
//        $user->role()->sync([1,2,3]);

        //6.更新指定权限id的额外字段  updateExistingPivot()
        // 直接使用update()是更新此用户所有权限额外字段
//        $user = BlogUser::find(3);
//        $roleId = 2;
////        $user->role()->updateExistingPivot($roleId,['detail' => '超级管理员权限']);
//        $user->role()->update(['detail' => '测试权限']); //更新此用户所有权限额外字段

        return view('data');
    }

}
